﻿using System.Collections.Generic;
using System.Reflection;
using JetBrains.Annotations;

namespace MugenInjection.Interception.Interface
{
    /// <summary>
    /// Represent an base interface for all interceptors.
    /// </summary>
    public interface IInterceptor
    {
        /// <summary>
        /// Gets a proxy object for the <see cref="IInterceptor"/>.
        /// </summary>
        IProxy Proxy { get; }

        /// <summary>
        /// Gets or sets the target of the interception.
        /// </summary>
        object Target { get; set; }

        /// <summary>
        /// Gets the type of current <see cref="IInterceptor"/>.
        /// </summary>
        InterceptorType InterceptorType { get; }

        /// <summary>
        /// Gets the <see cref="MemberInfo"/>. 
        /// </summary>
        MemberInfo Member { get; }

        /// <summary>
        /// Gets the chain of interceptors that will be executed before the target method is called.
        /// </summary>
        IList<IInterceptorProcess> Interceptors { get; }

        /// <summary>
        /// Indicates that no member of the base implementation.
        /// </summary>
        bool IsAbstract { get; }

        /// <summary>
        /// Invokes the original method of the member.
        /// </summary>
        void ProcessOriginal();

        /// <summary>
        /// Invokes the method in a target.
        /// </summary>
        void ProcessInTarget();
    }

    /// <summary>
    /// The type of <see cref="IInterceptor"/>.
    /// </summary>
    public enum InterceptorType
    {
        /// <summary>
        /// The method type.
        /// </summary>
        Method,

        /// <summary>
        /// The property get type.
        /// </summary>
        PropertyGet,

        /// <summary>
        /// The property set type.
        /// </summary>
        PropertySet,

        /// <summary>
        /// The event add type.
        /// </summary>
        EventAdd,

        /// <summary>
        /// The event remove type.
        /// </summary>
        EventRemove,

        /// <summary>
        /// The unknown type.
        /// </summary>
        Unknown
    }
}